"""推荐算法服务接口抽象层"""
from abc import ABC, abstractmethod
from typing import List, Dict, Any, Optional
from app.models.user import UserProfile
from app.models.question import Question
from app.models.training import TrainingSession, AnswerRecord


class RecommendationService(ABC):
    """推荐算法服务抽象基类"""
    
    @abstractmethod
    async def recommend_questions(
        self,
        user_id: str,
        count: int = 10,
        difficulty: Optional[str] = None,
        category: Optional[str] = None,
        exclude_question_ids: Optional[List[str]] = None
    ) -> List[str]:
        """
        推荐题目
        
        Args:
            user_id: 用户ID
            count: 推荐数量
            difficulty: 难度过滤
            category: 分类过滤
            exclude_question_ids: 排除的题目ID列表
            
        Returns:
            推荐的题目ID列表
        """
        pass
    
    @abstractmethod
    async def recommend_study_materials(
        self,
        user_id: str,
        weak_areas: List[str],
        count: int = 5
    ) -> List[Dict[str, Any]]:
        """
        推荐学习材料
        
        Args:
            user_id: 用户ID
            weak_areas: 薄弱领域列表
            count: 推荐数量
            
        Returns:
            推荐的学习材料列表
        """
        pass
    
    @abstractmethod
    async def recommend_training_plan(
        self,
        user_id: str,
        duration_days: int,
        current_level: float
    ) -> Dict[str, Any]:
        """
        推荐训练计划
        
        Args:
            user_id: 用户ID
            duration_days: 备考天数
            current_level: 当前水平（0-100）
            
        Returns:
            训练计划详情
        """
        pass
    
    @abstractmethod
    async def update_user_preferences(
        self,
        user_id: str,
        question_id: str,
        is_correct: bool,
        time_spent: float,
        feedback: Optional[str] = None
    ) -> None:
        """
        更新用户偏好（基于用户行为）
        
        Args:
            user_id: 用户ID
            question_id: 题目ID
            is_correct: 是否正确
            time_spent: 花费时间（秒）
            feedback: 可选反馈
        """
        pass


class MockRecommendationService(RecommendationService):
    """模拟推荐服务实现（用于开发测试）"""
    
    async def recommend_questions(
        self,
        user_id: str,
        count: int = 10,
        difficulty: Optional[str] = None,
        category: Optional[str] = None,
        exclude_question_ids: Optional[List[str]] = None
    ) -> List[str]:
        """模拟题目推荐"""
        # 模拟推荐逻辑：基于用户薄弱环节推荐
        base_questions = [f"q_{i:03d}" for i in range(1, 101)]
        
        if exclude_question_ids:
            base_questions = [q for q in base_questions if q not in exclude_question_ids]
        
        # 简单的推荐逻辑：优先推荐中等难度的题目
        recommended = base_questions[:count]
        return recommended
    
    async def recommend_study_materials(
        self,
        user_id: str,
        weak_areas: List[str],
        count: int = 5
    ) -> List[Dict[str, Any]]:
        """模拟学习材料推荐"""
        materials = []
        for area in weak_areas[:count]:
            materials.append({
                "type": "study_material",
                "title": f"{area}基础理论",
                "description": f"重点学习{area}的核心概念和重要条文",
                "priority": "high",
                "estimated_time": "2小时",
                "category": area
            })
        return materials
    
    async def recommend_training_plan(
        self,
        user_id: str,
        duration_days: int,
        current_level: float
    ) -> Dict[str, Any]:
        """模拟训练计划推荐"""
        # 根据备考天数和当前水平计算每日目标
        target_accuracy = min(85.0, current_level + (duration_days * 0.1))
        daily_questions = 30 if duration_days >= 180 else (50 if duration_days >= 90 else 80)
        daily_hours = 2.5 if duration_days >= 180 else (3.5 if duration_days >= 90 else 5.0)
        
        return {
            "duration_days": duration_days,
            "daily_target_hours": daily_hours,
            "daily_target_questions": daily_questions,
            "target_accuracy": target_accuracy,
            "phases": [
                {
                    "phase": 1,
                    "name": "基础阶段",
                    "duration": duration_days // 3,
                    "focus": "基础知识学习",
                    "target_accuracy": current_level + 5
                },
                {
                    "phase": 2,
                    "name": "强化阶段",
                    "duration": duration_days // 3,
                    "focus": "专项训练",
                    "target_accuracy": current_level + 10
                },
                {
                    "phase": 3,
                    "name": "冲刺阶段",
                    "duration": duration_days - (duration_days // 3) * 2,
                    "focus": "模拟考试",
                    "target_accuracy": target_accuracy
                }
            ]
        }
    
    async def update_user_preferences(
        self,
        user_id: str,
        question_id: str,
        is_correct: bool,
        time_spent: float,
        feedback: Optional[str] = None
    ) -> None:
        """模拟更新用户偏好"""
        # 在真实实现中，这里会更新用户的学习偏好模型
        pass


# 工厂函数
def get_recommendation_service() -> RecommendationService:
    """
    获取推荐服务实例
    
    Returns:
        推荐服务实例
    """
    # 可以返回基于多臂赌博机算法的实现
    # return MultiArmedBanditService()
    
    # 默认返回模拟服务
    return MockRecommendationService()

